// 8、type
// type可以为任意类型创建别名，让代码更简洁、可读性更强，同时能更方便地进行类型复用和扩展

// 一、基本用法
// 类型别名使用type关键字定义，type后类型名称,例如下面
type num = number
let price: num
price = 100

// 二、联合类型 
// 联合类型是一种高级类型，它表示一个值可以是几种不听类型之一
type Status = number | string   //定义一个Status的数据类型，值只能是数字或字符串类型
function printStatus(data: Status): void {
    console.log('printStatus', data);

}
printStatus('系统异常')
printStatus(404)
// printStatus(false)  报错

type Gender = '男' | '女'  //定义一个Gender的数据类型，值只能是字符串男/女
function printGender(data: Gender): void {
    console.log('printGender', data);
}
printGender('男')
printGender('女')
// printGender('张三')   //报错

// 三、交叉类型
//  交叉类型允许将多个类型合并为一个类型，合并后的类型将拥有所有被合并类
// 型的成员，交叉类型通常用于对象类型
type Area = {
    height: number,
    width: number,
    aaa: string,
    // bbb:number
}
type Address = {
    num: number,
    cell: number,
    room: string,
    aaa: string,
    // bbb:string
}

type House = Area & Address
let house: House = {
    height: 100,
    width: 100,
    num: 100,
    cell: 100,
    room: '中骏',
    aaa: '属性相同',
    // bbb:'属性不相同',   //报错，注意：此处不能写never,因为never是类型，这里需要写的是值，类型不是值
    // Area和Address中的属性少一个或者多一个都会报错
    // 如果有属性类名一样，则比较字段属性，属性相同则为该字段为该相同属性，如果不相同，则报错，提升该类名为never
}


// 9、一个特殊的情况！！！，重点！！！
// 代码1(逻辑正常)
// 在函数定义时，限制函数返回值为void那么函数的返回值就必须是空
function demo(): void {
    return undefined
    // return ''      //报错
    // return null    //报错
    // return false   //报错
    // return 0       //报错
}
demo()

// 代码2(逻辑正常)
type LogFun = () => void
const f1: LogFun = function () {
    return 999   // 这里不论返回什么，这里应该漂红，报错提示，因为上面定义的返回类型为void
    // 但是 并没有漂红报错
}
let res1 = f1()
console.log('result1', res1);   //打印的是 999
const f2: LogFun = () => '哈哈哈'
let res2 = f2()
console.log('result2', res2);   //打印的是 哈哈哈

// 具体原因如下：官方是为了确保类似下面的几行代码成立(官方解释原话)
const arrType = [1, 2, 3]
const dstType = [0]
arrType.forEach((item)=>{
    console.log('(item) => dstType.push(item)',dstType.push(item));
    
})


// 正常情况下 forEach循环应该是这样的
let mouarr = [1,2,3,4]
mouarr.forEach((item) => {})
// 当箭头函数的代码体只有一个的时候可以将{}花括号去掉，
// 去掉花括号后箭头函数会自己return返回代码体的执行结果
// 然后(item) => dstType.push(item)返回的就是dstType.push(item)的结果，那么他是有值的

// 虽然f1和f2这两个方法返回的有值，但是不能拿这个返回值进行逻辑操作，
// 因为void通常用于函数返回值的声明，含义:【函数不返回任何值,调用者也不应依赖其返回值进行任何操作】

// 官方文档详解地址  https://www.typescriptlang.org/docs/handbook/2/functions.html#assignability-of-functions
